<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>闭包</title>
</head>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<script>

    let func  = function () {
        let a = 1;
        return function () {
            a++;
            console.log(a)
        }
    };
    let f = func();
    f();
    f();
    f();

    let nodes = document.getElementsByTagName('div');
    for (var i = 0, len = nodes.length ; i < len; i++) {
        (function (i) {
            nodes[i].addEventListener('click', function () {
                console.log(i)
            })
        })(i)
    }

    // ---------------- 1 ----------------
    let mult = function () {
        var a = 1;
        for (var i = 0, l = arguments.length; i < l; i++) {
            a = a * arguments[i];
        }
        return a;
    }
    console.log( mult(2, 2 , 3), 'mult');
    // 问题: 这样的话每次都会重新计算 对于相同的参数来说有些浪费 于是我们可以加入缓存
    // ------------------ 2 -----------------
    let cache = {}
    let multCache = function () {
        var args = Array.prototype.join.call(arguments, ',');
        if (cache[args]) {
            return cache[args]
        }
        var a = 1;
        for (let i = 0, l = arguments.length; i < l; i++) {
            a = a * arguments[i]
        }
        return cache[ args ] = a;

    }
    console.log(multCache(1, 2, 3), 'multCache(1, 2, 3)');
    console.log(multCache(1, 2, 3), 'multCache(1, 2, 3)');
    console.log(multCache(1, 33, 2), 'multCache(1, 33, 2)');
    // 问题: 可以发现 cache 其实只是在 multCache 函数里面使用 但是我们却把它暴露到全局
    // ----------------- 3----------------
    let mult3 = (function () {
        var cache = {};
        return function () {
            var args = Array.prototype.join.call(arguments, ',');
            if ( args in cache ) {  // 当值为假值 0 第二个函数的判断不通过会重新计算
                return cache[args]
            }
            var a = 1;
            for (let i = 0, l = arguments.length; i < l; i++) {
                a = a * arguments[i]
            }
            return cache[ args ] = a
        }
    })()

    console.log('mult3(1, 2, 3)', mult3(1, 2, 3))
    console.log('mult3(1, 2, 3)', mult3(1, 2, 3))
    console.log('mult3(1, 3, 3)', mult3(1, 3, 3))
    
    // 显然 这个函数混杂了太多东西 我们将一些能够独立的代码独立出来
    // -------------- 4 ------------
    var mult4 = (function () {
        var cache = {};
        var calculate = function () {
            var a = 1;
            for (let i = 0, l = arguments.length; i < l; i++ ) {
                a = a * arguments[i]
            }
            return a
        }
        return function () {
            var args = Array.prototype.join.call(arguments, ',');
            if (args in cache ) {
                return cache[args]
            }
            return cache[args] = calculate.apply(null, arguments)
        }
    })()
    console.log('mult4(1, 2, 3)', mult4(1, 2, 3))
    console.log('mult4(1, 2, 3)', mult4(1, 2, 3))
    console.log('mult4(1, 3, 3)', mult4(1, 3, 3))


    // 2 延长局部变量的寿命
    // 由于一些低端的浏览器存在bug 所以会导致img有 30% 的情况下并不会发送成功
    let report = function (src) {
        var img = new Image() // 由于img 是局部变量 在函数执行完毕后便会销毁 所以有时候 请求还未来的及发送
        img.src = src
    }
    report('https://img.zcool.cn/community/04d5c35540a3090000017c50c756c1.jpg@80w_80h_1c_1e_1o_100sh.jpg')

    // 用闭包把img变量封闭起来
    let report2 = (function () {
        var imgs = [];
        return function (src) {
            var img = new Image()
            imgs.push(img)
            img.src = src
        }
    })()
    report2('https://img.zcool.cn/community/04d5c35540a3090000017c50c756c1.jpg@80w_80h_1c_1e_1o_100sh.jpg')

</script>
</body>
</html>